import React, { FC, useRef, useState, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import cl from 'classnames';
import './index.less';
import clonedeep from 'clonedeep';
import previewFields from '@/components/editor/Schema/preview';
import { isParentNode } from '@/components/editor/utils';

import {
  useDragDrop,
  useDrop,
  useDrag,
} from '@/components/editor/utils/dragDrop';

interface DragData {
  data: any;
  dragIndex: number;
  dragParentId: string;
}
interface Props {
  data: any;
  parentId: string;
  index: number;
}

interface CollectedProps {
  canDrop: boolean;
  isOver: boolean;
}

const Item = ({ data, parentId, index }) => {
  const selector = useCallback(
    (_) => ({
      state: _,
    }),
    [],
  );
  const { state } = useSelector(selector);
  const { focusId, dataCenter } = state.layout;

  const dispatch = useDispatch();
  const dragRef = useRef<HTMLDivElement | null>(null);
  const dropRef = useRef<HTMLDivElement | null>(null);

  const dragDrop = useDragDrop({
    dropRef,
    dragRef,
    data,
  });

  const [{ canDrop, isOver }, drop] = useDrop(dragDrop.useDrop());

  const [{ isDragging }, drag, connectDragPreview] = useDrag(
    dragDrop.useDrag(),
  );

  const { dragHighlight } = dragDrop;

  // const [{ canDrop, isOver }, drop] = useDrop<DragData, {}, CollectedProps>(
  //   () => ({
  //     accept: 'CRAD',
  //     drop: (item, monitor) => {
  //       if (monitor.didDrop()) {
  //         return;
  //       }
  //       //没有id 是新增,有id是移动
  //       if (!item.data.id) {
  //         console.log('没有id');
  //         dispatch({
  //           type: 'layout/appendCom',
  //           payload: {
  //             hoverParentId: parentId,
  //             hoverIndex: index,
  //             data: clonedeep(data),
  //             item: clonedeep(item.data),
  //             positionDown,
  //           },
  //         });
  //       } else {
  //         console.log('有id');
  //         dispatch({
  //           type: 'layout/moveCom',
  //           payload: {
  //             hoverParentId: parentId,
  //             hoverIndex: index,
  //             dragParentId: item.dragParentId,
  //             dragIndex: item.dragIndex,
  //             data: clonedeep(data),
  //             item: clonedeep(item.data),
  //             positionDown,
  //           },
  //         });
  //       }

  //       return undefined;
  //     },
  //     hover: (item, monitor) => {

  //       // 只检查被hover的最小元素
  //       const didHover = monitor.isOver({ shallow: true });
  //       if (didHover && dropRef.current) {
  //         // Determine rectangle on screen
  //         const hoverBoundingRect = dropRef.current.getBoundingClientRect();
  //         // Get vertical middle
  //         const hoverMiddleY =
  //           (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
  //         // Determine mouse position

  //         const clientOffset = monitor.getClientOffset();
  //         // const dragOffset = monitor.getSourceClientOffset()

  //         if (clientOffset) {
  //           // Get pixels to the top
  //           const hoverClientY = clientOffset.y - hoverBoundingRect.top;

  //           if (hoverClientY <= hoverMiddleY) {
  //             setPosition(false);
  //           }
  //           // Dragging upwards
  //           if (hoverClientY > hoverMiddleY) {
  //             setPosition(true);
  //           }
  //         }
  //       }
  //     },
  //     collect: (monitor) => ({
  //       isOver: monitor.isOver({
  //         shallow: true,
  //       }),
  //       canDrop: monitor.canDrop(),
  //     }),
  //   }),
  //   [data, parentId, positionDown, index],
  // );

  // const [{ isDragging }, drag, connectDragPreview] = useDrag(() => {
  //   const dragData = {
  //     data,
  //     dragIndex: index,
  //     dragParentId: parentId,
  //   };
  //   return {
  //     type: 'CRAD',
  //     item:(monitor)=>{
  //       return dragData
  //     } ,
  //     end(item, monitor) {
  //     },
  //     collect: (monitor) => ({
  //       isDragging: monitor.isDragging(),
  //     }),
  //   };
  // }, [data, index, parentId]);

  drop(drag(dragRef));

  const handleFocus = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.stopPropagation();

    dispatch({
      type: 'layout/focus',
      payload: data.id,
    });
  };

  const handleRemove = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    e.stopPropagation();

    dispatch({
      type: 'layout/removeCom',
      payload: {
        parentId,
        id: data.id,
      },
    });
  };

  const action = (
    <span onClick={handleRemove} className="focus-remove">
      <svg
        className="w-4 h-4 bg"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
        />
      </svg>
    </span>
  );

  const className = cl('relative', {
    opacity: isDragging,
    'outline-blue': focusId === data.id,
  });

  const CurrentTag = previewFields[data.type] as any;

  return (
    <div onClick={handleFocus} ref={dropRef} className={className}>
      {focusId === data.id && action}
      {isOver &&
      canDrop &&
      dragHighlight.id == data.id &&
      dragHighlight.mode == 'top' ? (
        <div className="border my-1" />
      ) : null}
      <div className="item-wrap" ref={dragRef}>
        <CurrentTag {...data.props}>
          {!isParentNode(data.type)
            ? data.props.children
            : data.sons &&
              data.sons.map((subId, index) => {
                const sub = dataCenter[subId];
                return (
                  <Item
                    parentId={data.id}
                    index={index}
                    data={sub}
                    key={sub.id}
                  />
                );
              })}
        </CurrentTag>
      </div>
      {isOver &&
      canDrop &&
      dragHighlight.id == data.id &&
      dragHighlight.mode == 'bottom' ? (
        <div className="border my-1" />
      ) : null}
    </div>
  );
};

export default Item;
